package tcln.sors.client.core.utils;

import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.HashMap;
import java.util.Map;

/**
 * A new font class providing DSL API for {@link Font} manipulation.
 * 
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public class JFont {
    String name = "Dialog";
    boolean bold;
    boolean italic;
    boolean underline;
    boolean strikethrough;
    int size = 12;

    /**
     * Constructs this font with default information.
     */
    public JFont() {
        // default
    }

    /**
     * Constructs this font from another font.
     * 
     * @param another
     */
    public JFont(JFont another) {
        this.bold = another.bold;
        this.italic = another.italic;
        this.underline = another.underline;
        this.strikethrough = another.strikethrough;
        this.size = another.size;
        this.name = another.name;
    }

    /**
     * Specifies font name. This can be a font face name or a font family name, and may represent either a logical font
     * or a physical font found in {@link Font}'s {@link java.awt.GraphicsEnvironment}.
     * 
     * @param name
     *            Font name.
     * @return This instance.
     */
    public JFont name(String name) {
        this.name = name;
        return this;
    }

    /**
     * Specifies style: bold.
     * 
     * @return This instance.
     */
    public JFont bold() {
        this.bold = true;
        return this;
    }

    /**
     * Specifies style: italic.
     * 
     * @return This instance.
     */
    public JFont italic() {
        this.italic = true;
        return this;
    }

    /**
     * Specifies style: underline (A line that is drawn underneath text).
     * 
     * @return This instance.
     */
    public JFont underline() {
        this.underline = true;
        return this;
    }

    /**
     * Specifies style: strikethrough (A horizontal line that is drawn through the text).
     * 
     * @return This instance.
     */
    public JFont strikethrough() {
        this.underline = true;
        return this;
    }

    /**
     * Clears all styles.
     * 
     * @return This instance.
     */
    public JFont plain() {
        this.bold = this.underline = this.italic = false;
        return this;
    }

    /**
     * Sets font size, should NOT be smaller than 8.
     * 
     * @param size
     * @return This instance.
     */
    public JFont size(int size) {
        this.size = size;
        return this;
    }

    /**
     * Creates a new {@link Font} matching all specified requirements.
     * 
     * @return a new {@link Font} instance.
     */
    public Font toJavaFont() {
        size = Math.max(size, 8); // a text should not be smaller than 8

        int style = Font.PLAIN;
        if (bold) {
            style = Font.BOLD;
        }
        if (italic) {
            style += Font.ITALIC;
        }

        Font font = new Font(name, style, size);

        if (underline || strikethrough) {
            Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();

            if (underline) {
                map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
            }

            if (strikethrough) {
                map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
            }

            font = font.deriveFont(map);
        }

        return font;
    }
}
